#pragma once
#include <unordered_map>
#include "../comm/httplib.h"

#include "../comm/Log.hpp"

typedef enum
{
    UNLOGIN,
    LOGIN
} ss_status;

class Session
{
public:
    Session(int ssid) : _ssid(ssid), _status(UNLOGIN)
    {
        LOG(INFO, "Session: %p has be Build\n", this);
    }
    ~Session()
    {
        LOG(INFO, "Session: %p has be Destroyed\n", this);
    }

    void set_user(int uid) { _uid = uid; }
    int get_user() { return _uid; }
    bool is_login() { return _status == LOGIN; }
    void set_status(ss_status status) { _status = status; }
    int GetSsid() { return _ssid; }

private:
    int _ssid;
    int _uid;
    ss_status _status;
};

typedef std::shared_ptr<Session> session_ptr;

class SessionManage
{
public:
    SessionManage()
        : _next_ssid(1)
    {
    }
    ~SessionManage()
    {
    }

    session_ptr create_session(int uid, ss_status status)
    {
        std::unique_lock<std::mutex> lock(_mtx);

        session_ptr sp(new Session(_next_ssid));
        _session.insert(std::make_pair(_next_ssid, sp));
        sp->set_user(uid);
        sp->set_status(status);
        ++_next_ssid;

        return sp;
    }
    session_ptr get_session_by_ssid(int ssid)
    {
        std::unique_lock<std::mutex> lock(_mtx);

        auto it = _session.find(ssid);
        if (it == _session.end())
        {
            return session_ptr();
        }
        return it->second;
    }
    void remove_session(int ssid)
    {
        std::unique_lock<std::mutex> lock(_mtx);

        _session.erase(ssid);
    }

    void add_session(int ssid, session_ptr sp)
    {
        std::unique_lock<std::mutex> lock(_mtx);

        _session.insert(std::make_pair(ssid, sp));
    }

private:
    int _next_ssid; // 下一个会话的 id
    std::mutex _mtx; 
    std::unordered_map<int, session_ptr> _session; // ssid -> session
};
